package app.modules.security.application.web;

import app.modules.common.dto.web.WebIdDTO;
import app.modules.common.util.web.PageUtil;
import app.modules.security.business.service.function.FunctionPermissionRelationService;
import app.modules.security.business.service.function.FunctionResourceRelationService;
import app.modules.security.business.service.function.FunctionService;
import app.modules.security.dto.web.function.WebAssignPermissionDTO;
import app.modules.security.dto.web.function.WebAssignResourceDTO;
import app.modules.security.dto.web.function.WebFunctionDTO;
import app.modules.security.dto.web.function.WebFunctionQueryDTO;
import app.modules.security.dto.web.function.WebFunctionSaveDTO;
import app.modules.security.dto.web.function.WebFunctionUpdateDTO;
import app.modules.security.dto.web.permission.WebPermissionDTO;
import app.modules.security.dto.web.resource.WebResourceDTO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jasmine.framework.web.entity.WebResult;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;


/**
 * @author mh.z
 */
@Tag(name = "接口管理/功能API")
@RestController
public class FunctionController {
    private final FunctionService functionService;
    private final FunctionResourceRelationService functionResourceRelationService;
    private final FunctionPermissionRelationService functionPermissionRelationService;

    public FunctionController(FunctionService functionService,
                              FunctionResourceRelationService functionResourceRelationService,
                              FunctionPermissionRelationService functionPermissionRelationService) {
        this.functionService = functionService;
        this.functionResourceRelationService = functionResourceRelationService;
        this.functionPermissionRelationService = functionPermissionRelationService;
    }

    @Operation(summary = "分页查询功能")
    @PostMapping("/api/security/function/pageFunctionsByCond")
    public ResponseEntity<WebResult<List<WebFunctionDTO>>> pageWebFunctionDTOsByCond(
            @RequestBody WebFunctionQueryDTO queryDTO) {
        Page page = PageUtil.getPage(queryDTO);

        List<WebFunctionDTO> recordList = functionService.pageWebFunctionDTOsByCond(queryDTO, page);
        WebResult result = PageUtil.getResult(recordList, page);

        return result.toOkEntity();
    }

    @Operation(summary = "查询指定 ID 的功能")
    @PostMapping("/api/security/function/getFunctionById")
    public ResponseEntity<WebResult<WebFunctionDTO>> getFunctionById(
            @RequestBody WebIdDTO dto) {
        Long id = dto.getId();
        WebFunctionDTO functionDTO = functionService.getWebFunctionDtoById(id);

        return WebResult.success(functionDTO).toOkEntity();
    }

    @Operation(summary = "保存功能")
    @PostMapping("/api/security/function/saveFunction")
    public ResponseEntity<WebResult<WebFunctionDTO>> saveFunction(
            @Valid @RequestBody WebFunctionSaveDTO saveDTO) {
        WebFunctionDTO functionDTO = functionService.saveFunction(saveDTO);
        WebResult result = WebResult.success(functionDTO);

        return result.toOkEntity();
    }

    @Operation(summary = "更新功能")
    @PostMapping("/api/security/function/updateFunction")
    public ResponseEntity<WebResult<WebFunctionDTO>> updateFunction(
            @Valid @RequestBody WebFunctionUpdateDTO updateDTO) {
        WebFunctionDTO functionDTO = functionService.updateFunction(updateDTO);
        WebResult result = WebResult.success(functionDTO);

        return result.toOkEntity();
    }

    @Operation(summary = "删除指定 ID 的功能")
    @PostMapping("/api/security/function/deleteFunctionById")
    public ResponseEntity<WebResult<Object>> deleteFunctionById(
            @RequestBody WebIdDTO paramDTO) {
        Long recordId = paramDTO.getId();
        functionService.deleteRecordById(recordId);

        return WebResult.success().toOkEntity();
    }

    @Operation(summary = "查询指定功能的所有已分配资源")
    @PostMapping("/api/security/function/listAssignedResources")
    public ResponseEntity<WebResult<List<WebResourceDTO>>> listAssignedResources(
            @RequestBody WebIdDTO paramDTO) {
        Long recordId = paramDTO.getId();
        List<WebResourceDTO> recordList = functionResourceRelationService.listAssignedResources(recordId);

        return WebResult.success(recordList).toOkEntity();
    }

    @Operation(summary = "查询指定功能的所有已分配权限")
    @PostMapping("/api/security/function/listAssignedPermissions")
    public ResponseEntity<WebResult<List<WebPermissionDTO>>> listAssignedPermissions(
            @RequestBody WebIdDTO paramDTO) {
        Long recordId = paramDTO.getId();
        List<WebPermissionDTO> recordList = functionPermissionRelationService.listAssignedPermissions(recordId);

        return WebResult.success(recordList).toOkEntity();
    }

    @Operation(summary = "向指定功能分配权限")
    @PostMapping("/api/security/function/assignPermissions")
    public ResponseEntity<WebResult<Object>> assignPermissions(
            @RequestBody WebAssignPermissionDTO assignDTO) {
        Long functionId = assignDTO.getFunctionId();
        List<Long> permissionIdList = assignDTO.getPermissionIds();
        functionPermissionRelationService.assignPermission(functionId, permissionIdList);

        return WebResult.success().toOkEntity();
    }

    @Operation(summary = "向指定功能分配资源")
    @PostMapping("/api/security/function/assignResources")
    public ResponseEntity<WebResult<Object>> assignResources(
            @RequestBody WebAssignResourceDTO assignDTO) {
        Long functionId = assignDTO.getFunctionId();
        List<Long> resourceIdList = assignDTO.getResourceIds();
        functionResourceRelationService.assignResource(functionId, resourceIdList);

        return WebResult.success().toOkEntity();
    }

}
